package com.funtonow.jqdk.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * @author Jiajien
 * @date 2019/7/15
 * 腾讯云接口参数鉴权
 */
public class TXAuthentication {

    /**
     * @param map
     * @return
     */
    public static String sortMapByKey(Map<String, String> map, String key) {
        Map<String, String> sortedParams = new TreeMap<>(map);
        Set<Map.Entry<String, String>> entrySet = sortedParams.entrySet();
        StringBuilder baseString = new StringBuilder();
        for (Map.Entry<String, String> params : entrySet) {
            if (params.getValue() != null && !StringUtil.isEmpty(params.getKey().trim())
                    && !"sign".equals(params.getKey().trim()) && !StringUtil.isEmpty(params.getValue().trim())) {
                try {
                    baseString.append(params.getKey().trim()).append("=")
                            .append(URLEncoder.encode(params.getValue().trim(), "UTF-8")).append("$");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        if (baseString.length() > 0) {
            baseString.deleteCharAt(baseString.length() - 1).append("&app_key=" + key);
        }
        LogUtil.i("拼接appsign " + baseString.toString());

        return MD5Encode(baseString.toString());
    }

    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     * @throws UnsupportedEncodingException
     */
    public static String createLinkStringByGet(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            try {
                value = URLEncoder.encode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }


    /**
     * 返回大写MD5
     *
     * @param charsetname
     * @return
     */
    private static String MD5Encode(String charsetname) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = charsetname.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * SIGN签名生成算法-JAVA版本
     *
     * @param params  请求参数集，所有参数必须已转换为字符串类型
     * @param app_key
     * @return String
     * @throws IOException
     */
    public static String getSignature(Map<String, String> params, String app_key) {
        // 先将参数以其参数名的字典序升序进行排序
        Map<String, String> sortedParams = new TreeMap<>(params);
        Set<Map.Entry<String, String>> entrys = sortedParams.entrySet();
        // 遍历排序后的字典，将所有参数按"key=value"格式拼接在一起
        StringBuilder baseString = new StringBuilder();
        for (Map.Entry<String, String> param : entrys) {
            //sign参数 和 空值参数 不加入算法
            if (param.getValue() != null && !"".equals(param.getKey().trim()) && !"sign".equals(param.getKey().trim()) && !"".equals(param.getValue().trim())) {
                try {
                    baseString.append(param.getKey().trim()).append("=").append(URLEncoder.encode(param.getValue().trim(), "UTF-8")).append("&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        if (baseString.length() > 0) {
            baseString.deleteCharAt(baseString.length() - 1).append("&app_key=" + app_key);
        }
        // 使用MD5对待签名串求签
        return MD5Encode(baseString.toString());

    }


}
